using System;
using System.Collections.Generic;
using System.Linq;
using RealtimeCollabGame.Domain.ValueObjects;

namespace RealtimeCollabGame.Domain.ValueObjects;

public class Canvas
{
    public int Width { get; }
    public int Height { get; }
    
    // 画布数据：每个像素记录所属玩家ID和颜色
    private readonly Dictionary<Position, PixelData> _pixels = new();
    
    public Canvas(int width, int height)
    {
        if (width <= 0) throw new ArgumentException("画布宽度必须大于0", nameof(width));
        if (height <= 0) throw new ArgumentException("画布高度必须大于0", nameof(height));
        
        Width = width;
        Height = height;
    }
    
    public bool CanPaint(Position position, BrushSize brushSize)
    {
        if (!position.IsWithinBounds(Width, Height))
            return false;
            
        // 检查画笔范围内的所有像素是否可绘制
        var affectedPixels = GetAffectedPixels(position, brushSize);
        return affectedPixels.All(p => !_pixels.ContainsKey(p) || _pixels[p].IsNeutral);
    }
    
    public void Paint(Position position, BrushSize brushSize, PlayerColor color)
    {
        if (!CanPaint(position, brushSize))
            throw new InvalidOperationException("无法在此位置绘制");
            
        var affectedPixels = GetAffectedPixels(position, brushSize);
        
        foreach (var pixel in affectedPixels)
        {
            _pixels[pixel] = new PixelData(color, false);
        }
    }
    
    public Dictionary<Guid, int> GetPlayerAreas()
    {
        var playerAreas = new Dictionary<Guid, int>();
        
        foreach (var pixel in _pixels.Values)
        {
            if (pixel.PlayerId.HasValue)
            {
                if (!playerAreas.ContainsKey(pixel.PlayerId.Value))
                    playerAreas[pixel.PlayerId.Value] = 0;
                playerAreas[pixel.PlayerId.Value]++;
            }
        }
        
        return playerAreas;
    }
    
    public int GetTotalPaintedArea()
    {
        return _pixels.Count;
    }
    
    public void Clear()
    {
        _pixels.Clear();
    }
    
    public CanvasSnapshot GetSnapshot()
    {
        return new CanvasSnapshot(Width, Height, new Dictionary<Position, PixelData>(_pixels));
    }
    
    private List<Position> GetAffectedPixels(Position center, BrushSize brushSize)
    {
        var pixels = new List<Position>();
        var radius = brushSize.Value / 2;
        
        for (int x = center.X - radius; x <= center.X + radius; x++)
        {
            for (int y = center.Y - radius; y <= center.Y + radius; y++)
            {
                var position = new Position(x, y);
                if (position.IsWithinBounds(Width, Height))
                {
                    pixels.Add(position);
                }
            }
        }
        
        return pixels;
    }
}

public record PixelData(PlayerColor Color, bool IsNeutral, Guid? PlayerId = null)
{
    public static PixelData CreateNeutral() => new(PlayerColor.Blue, true);
}

public record CanvasSnapshot(int Width, int Height, Dictionary<Position, PixelData> Pixels);


